package com.xlf.service.base.config;

import com.rabbitmq.client.ConnectionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.xlf.common.core.constant.MqConstant.Judge.*;

@Configuration
@Slf4j
public class RabbitMqConfig {


    @Autowired
    JudgeProperties judgeProperties;


    @Autowired
    RabbitAdmin rabbitAdmin;

    /**
     * 更新判题交换机、队列
     * @return
     */
    public void update() {

        rabbitAdmin.removeBinding(JudgeQueueBinding());
        rabbitAdmin.removeBinding(JudgeProblemDieBinding());
        rabbitAdmin.removeBinding(JudgeTestDieBinding());
        rabbitAdmin.removeBinding(JudgeTestQueueBinding());

        rabbitAdmin.deleteExchange(JUDGE_EXCHANGE);
        rabbitAdmin.deleteExchange(JUDGE_DIE_EXCHANGE);
        rabbitAdmin.deleteQueue(JUDGE_PROBLEM_QUEUE);
        rabbitAdmin.deleteQueue(JUDGE_TEST_QUEUE);
        rabbitAdmin.deleteQueue(JUDGE_TEST_QUEUE);
        rabbitAdmin.deleteQueue(JUDGE_TEST_DIE_QUEUE);


        //死信
        rabbitAdmin.declareExchange(JudgeDieExchange());
        rabbitAdmin.declareQueue(judgeTestDieQueue());
        rabbitAdmin.declareQueue(judgeProblemDieQueue());

        //正常
        rabbitAdmin.declareExchange(JudgeExchange());
        rabbitAdmin.declareQueue(judgeTestQueue());
        rabbitAdmin.declareQueue(judgeProblemQueue());


        rabbitAdmin.declareBinding(JudgeQueueBinding());
        rabbitAdmin.declareBinding(JudgeProblemDieBinding());
        rabbitAdmin.declareBinding(JudgeTestDieBinding());
        rabbitAdmin.declareBinding(JudgeTestQueueBinding());


    }



    /**
     * 判题服务交换机
     * @return 直接交换机
     */
    DirectExchange JudgeExchange(){

//        rabbitAdmin.deleteExchange(JUDGE_EXCHANGE);
        DirectExchange exchange = ExchangeBuilder
                .directExchange(JUDGE_EXCHANGE)
                .durable(true) //持久化
                .build();
//        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }


    /**
     * 判题服务死信交换机
     * @return 直接交换机
     */
    DirectExchange JudgeDieExchange(){

//        rabbitAdmin.deleteExchange(JUDGE_DIE_EXCHANGE);
        DirectExchange exchange = ExchangeBuilder
                .directExchange(JUDGE_DIE_EXCHANGE)
                .durable(true) //持久化
                .build();
//        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }

    /**
     *判题队列
     * @return
     */
    Queue judgeProblemQueue(){

//        rabbitAdmin.deleteQueue(JUDGE_PROBLEM_QUEUE);
        Queue queue = QueueBuilder
                .durable(JUDGE_PROBLEM_QUEUE)//持久化
                .maxLength(judgeProperties.getMaxSubmit()) //最大长度
                .overflow(QueueBuilder.Overflow.dropHead) //满了丢死信交换机策略
                .deadLetterExchange(JUDGE_DIE_EXCHANGE) //死信交换机
                .deadLetterRoutingKey(JUDGE_PROBLEM_DIE_KEY) //死信routerKey
                .build();
//        rabbitAdmin.declareQueue(queue);
        return queue;
    }

    /**
     *用例测试队列
     * @return
     */
    Queue judgeTestQueue(){

//        rabbitAdmin.deleteQueue(JUDGE_TEST_QUEUE);
        Queue queue = QueueBuilder
                .durable(JUDGE_TEST_QUEUE)//持久化
                .maxLength(judgeProperties.getMaxSubmit()) //最大长度
                .overflow(QueueBuilder.Overflow.dropHead) //满了丢死信交换机策略
                .deadLetterExchange(JUDGE_DIE_EXCHANGE) //死信交换机
                .deadLetterRoutingKey(JUDGE_TEST_DIE_KEY) //死信routerKey
                .build();
//        rabbitAdmin.declareQueue(queue);
        return queue;
    }

    /**
     *用例测试死信队列
     * @return
     */
    Queue judgeTestDieQueue(){

//        rabbitAdmin.deleteQueue(JUDGE_TEST_DIE_QUEUE);
        Queue queue = QueueBuilder
                .durable(JUDGE_TEST_DIE_QUEUE)//持久化
                .build();

//        rabbitAdmin.declareQueue(queue);
        return queue;
    }

    /**
     *判题死信队列
     * @return
     */
    Queue judgeProblemDieQueue(){

//        rabbitAdmin.deleteQueue(JUDGE_PROBLEM_DIE_QUEUE);
        Queue queue = QueueBuilder
                .durable(JUDGE_PROBLEM_DIE_QUEUE)//持久化
                .build();

//        rabbitAdmin.declareQueue(queue);
        return queue;
    }

    /**
     * 绑定
     */
    @Bean
    public Binding JudgeQueueBinding() {
        Binding binding = BindingBuilder.bind(judgeProblemQueue())
                .to(JudgeExchange())
                .with(JUDGE_PROBLEM_KEY);

//        rabbitAdmin.removeBinding(binding);
//        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 绑定
     */
    @Bean
    public Binding JudgeProblemDieBinding() {
        Binding binding = BindingBuilder.bind(judgeProblemDieQueue())
                .to(JudgeDieExchange())
                .with(JUDGE_PROBLEM_DIE_KEY);

//        rabbitAdmin.removeBinding(binding);
//        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 绑定
     */
    @Bean
    public Binding JudgeTestQueueBinding() {

        Binding binding = BindingBuilder.bind(judgeTestQueue())
                .to(JudgeExchange())
                .with(JUDGE_TEST_KEY);
//        rabbitAdmin.removeBinding(binding);
//        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 绑定
     */
    @Bean
    public Binding JudgeTestDieBinding() {
        Binding binding = BindingBuilder.bind(judgeTestDieQueue())
                .to(JudgeDieExchange())
                .with(JUDGE_TEST_DIE_KEY);

//        rabbitAdmin.removeBinding(binding);
//        rabbitAdmin.declareBinding(binding);

        return binding;
    }

}
